	package com.vates.vsp.dao.implementacion;

import java.util.Date;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
import javax.persistence.PersistenceContext;
import javax.persistence.TypedQuery;

import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import com.vates.vsp.dao.DaoBaseReserva;
import com.vates.vsp.entidades.Reserva;

@Repository(value = "reservaDao")
public class ReservaDao implements DaoBaseReserva {

	@PersistenceContext(unitName = UNIT_NAME)
	private EntityManager em;

	public void setEm(EntityManager em) {
		this.em = em;
	}

	@Transactional
	public void guardar(Reserva reserva) {
		if (reserva != null)
			em.merge(reserva);
	}

	@Transactional
	public void eliminar(Reserva reserva) {
		if (reserva != null)
			em.remove(em.merge(reserva));
	}

	@Transactional
	public Reserva buscarPorId(Long id) {
		try {
			TypedQuery<Reserva> q = em.createQuery(
					"SELECT r FROM Reserva r WHERE r.idReserva= :id",
					Reserva.class);
			return q.setParameter("id", id).getSingleResult();
		} catch (NoResultException e) {
			return null;
		}
	}

	@Deprecated
	public Reserva buscarPorNombre(String nombre) {
		// declarado deprecated (obsoleto) porque las reservas no tienen nombre
		return null;
	}

	@Transactional
	public List<Reserva> buscarTodos() throws NoResultException {
		try {
			return em.createQuery("SELECT r FROM Reserva r", Reserva.class)
					.getResultList();
		} catch (NoResultException e) {
			return null;
		}
	}

	@Transactional
	public List<Reserva> buscarPorNumeroHotel(Long idHotel, Date fechaInferior,
			Date fechaSuperior) {
		try {
			TypedQuery<Reserva> q = em.createQuery(
							"SELECT r FROM Reserva r " +
							"WHERE r.tipoHabitacion.hotel.idHotel= :idHot " +
							"AND ((r.fechaIni BETWEEN :inferior AND :superior) AND (r.fechaFin BETWEEN :inferior AND :superior)) " +
							"ORDER BY r.fechaIni",	Reserva.class);
			q.setParameter("idHot", idHotel);
			q.setParameter("inferior", fechaInferior);
			q.setParameter("superior", fechaSuperior);
			
			return q.getResultList();
		} catch (NoResultException e) {
			return null;
		}
	}

	@Transactional
	public List<Reserva> buscarPorNumeroCliente(Long idCliente,
			Date fechaInferior, Date fechaSuperior) {
		try {
			TypedQuery<Reserva> q = em
					.createQuery(
							"SELECT r FROM Reserva r " +
							"WHERE r.cliente.idCliente= :idCli " +
							"AND ((r.fechaIni BETWEEN :inferior AND :superior) OR (r.fechaFin BETWEEN :inferior AND :superior)) " +
							"ORDER BY r.fechaIni",	Reserva.class);
			q.setParameter("idCli", idCliente);
			q.setParameter("inferior", fechaInferior);
			q.setParameter("superior", fechaSuperior);
			return q.getResultList();
		} catch (NoResultException e) {
			return null;
		}
	}
}
